<template>
  <div class="article-details" v-if="isVisible" :style="{
    display: isVisible ? 'block' : 'none',
    transform: isVisible ? 'translateY(0)' : 'translateY(100%)'
  }">
    <div class="article-details-header" v-if="Object.keys(articleDetailsData).length > 0">
      <van-icon name="arrow-left" class="close-details" @click="closeDetails" />
      <div class="details-header-title">{{ headerTitle }}</div>
      <i class="recommend-iconfont icon-favorites"></i>
    </div>

    <div class="article-details-content" ref="detailsContent" v-if="Object.keys(articleDetailsData).length > 0">
      <div class="article-details-title">{{ articleDetailsData.title }}</div>

      <div class="qustion">
        <div class="simple_author">{{ articleDetailsData.json_content?.simple_author?.[0] }}</div>
        <div class="question_brief">{{ articleDetailsData.json_content?.question_brief }}</div>
      </div>

      <div class="simple_answerer">{{ articleDetailsData.json_content?.simple_answerer }}</div>

      <div class="control-font-size">
        <i class="font-sm" @click="setFontSize(10)"></i>
        <i class="font-bg" @click="setFontSize(12)"></i>
        <i class="font-lg" @click="setFontSize(14)"></i>
      </div>

      <div class="article-details-img">
        <img :src="articleDetailsData.home_image" alt="" v-if="articleDetailsData.title != '一周的心情｜本周小记精选'">
      </div>

      <i class="one-icon one-icon-quote"
        v-if="articleText.length > 0 && articleText[0] && articleText[0].text !== ''"></i>

      <div class="article-details-text" v-if="articleText.length > 0">
        <p v-for="(item, index) in articleText" :key="index" :style="{ fontSize: currentFontSize + 'px' }">{{
          item.text }}</p>
      </div>

      <div class="article-details-weekimg" v-if="articleImg.length > 0 && articleDetailsData.title == '一周的心情｜本周小记精选'">
        <img :src="item.src" v-for="(item, index) in articleImg" :key="index">
      </div>

      <div class="editor">{{ articleDetailsData.json_content?.editor }}</div>

      <div class="copyright">{{ articleDetailsData.json_content?.copyright }}</div>

      <div class="article-details-author">
        <span>作者</span>
        <div class="author-box">
          <div class="author-left">
            <div class="author-avatar"
              :style="{ backgroundImage: 'url(' + articleDetailsData.author_list?.[0]?.web_url + ')' }"></div>
            <div class="author-info">
              <div class="author-name">{{ articleDetailsData.author_list?.[0]?.user_name }}</div>
              <div class="author-summary">{{ articleDetailsData.author_list?.[0]?.summary }}</div>
            </div>
          </div>
          <div class="follow-btn">关注</div>
        </div>
      </div>

      <div class="related-recommend" v-if="articleDetailsData.title != '一周的心情｜本周小记精选'">
        <span>相关推荐</span>
        <div class="recommend-articles" v-for="(item, index) in recommendArticlesList"
          :key="`recommend-${item.id}-${index}`" @click="handleRecommendClick(item)">
          <div class="type">问答</div>
          <div class="recommend-articles-info">
            <div class="recommend-articles-name">{{ item.title }}</div>
            <div class="recommend-articles-author">文／{{ item.author_list?.[0]?.user_name }}</div>
          </div>
        </div>
      </div>

      <div class="related-recommend" v-if="articleDetailsData.title == '一周的心情｜本周小记精选'">
        <span>相关推荐</span>
        <div class="recommend-articles" v-for="(item, index) in recommendWeeklyJournalsList"
          :key="`recommend-${item.id}-${index}`" @click="handleRecommendClick(item)">
          <div class="type">小记</div>
          <div class="recommend-articles-info">
            <div class="recommend-articles-name">{{ item.title }}</div>
            <div class="recommend-articles-author">文／{{ item.author_list?.[0]?.user_name }}</div>
          </div>
        </div>
      </div>

      <div class="comment-list" ref="commentList">
        <span>评论列表</span>
        <div class="comment-list-item" v-for="(item, index) in commentList" :key="`comment-${item.id}-${index}`">
          <div class="comment-list-item-head">
            <div class="comment-list-item-user">
              <div class="comment-user-avatar" :style="{ backgroundImage: 'url(' + item.user?.web_url + ')' }"></div>
              <div class="comment-user-name">{{ item.user?.user_name }}</div>
            </div>
            <div class="comment-input-date">{{ item.input_date?.replace(/-/g, '.').split(':').slice(0, 2).join(':') }}
            </div>
          </div>
          <div class="quoted-comment" v-if="item.quote !== '' && item.touser !== null">{{ item.touser?.user_name }}：{{
            item.quote }}</div>
          <div class="comment-content">{{ item.content }}</div>
          <div class="comment-function-icon">
            <i></i>
            <div class="praise">
              <i @click.stop="togglePraise(item)" :style="{
                backgroundImage: item.isPraised
                  ? `url(${require('../assets/detail-icon/praise-active.svg')})`
                  : `url(${require('../assets/detail-icon/praise.svg')})`
              }"></i>
              <span class="praisenum">{{ item.praisenum }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="article-details-bottom" v-if="Object.keys(articleDetailsData).length > 0">
      <div class="write-comments" @click="handleWriteComment">
        写一个评论...
      </div>

      <div class="bottom-function-icon">
        <div class="like">
          <i class="one-icon" :class="articleDetailsData.isLiked ? 'one-icon-liked' : 'one-icon-like'"
            @click="toggleLike(articleDetailsData)"></i>
          <span>{{ articleDetailsData.praisenum }}</span>
        </div>

        <div class="comment" @click="scrollToCommentList">
          <i></i>
          <span>{{ articleDetailsData.commentnum }}</span>
        </div>

        <i class="one-icon one-icon-share"></i>
      </div>
    </div>

    <div v-if="Object.keys(articleDetailsData).length == 0" class="loading">加载中...</div>

  </div>
</template>

<script>
import { getQADetail, getQAComments } from '@/api/api'
import { Icon } from 'vant'

export default {
  name: 'QADetail',
  components: {
    [Icon.name]: Icon
  },
  props: {
    articleId: {
      type: [String, Number],
      default: ''
    },
    isVisible: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      articleDetailsData: {},// 储存文章详情数据
      articleText: [],// 储存文章文本内容
      articleImg: [],// 储存文章图片路径
      recommendArticlesList: [],// 储存推荐文章列表
      commentList: [],// 储存评论列表
      currentFontSize: 10, // 文章字体大小默认10px
      lastScrollTop: 0, // 记录上次滚动位置
      headerTitle: '问答', // 头部标题
      recommendWeeklyJournalsList: [],// 存储推荐周报列表
    }
  },
  watch: {
    // 监听articleId变化，获取文章详情
    articleId: {
      handler(newId) {
        if (newId) {
          this.getArticleDetailsData(newId);
        }
      },
      immediate: true
    },
    // 监听isVisible变化，处理滚动事件
    isVisible: {
      handler(newVal) {
        if (newVal) {
          this.$nextTick(() => {
            this.$refs.detailsContent?.addEventListener('scroll', this.handleDetailsScroll);
            this.headerTitle = '问答';
          });
        } else {
          this.$refs.detailsContent?.removeEventListener('scroll', this.handleDetailsScroll);
        }
      }
    },
    // 监听文章详情数据变化，重置标题
    articleDetailsData() {
      this.$nextTick(() => {
        const scrollTop = this.$refs.detailsContent?.scrollTop || 0;
        this.headerTitle = scrollTop === 0 ? '问答' : (this.articleDetailsData.title || '问答');
      });
    }
  },
  methods: {
    // 根据文章id获取文章详情数据，显示详情页并处理相关数据
    getArticleDetailsData(id) {
      getQADetail(id)
        .then(res => {
          this.articleDetailsData = res.data
          this.articleImg = this.extractImgUrls(); // 提取img
          this.articleText = this.extractPTags(); // 提取p标签
          this.fetchRecommendArticles();

          // 文章数据加载完成后绑定滚动事件
          this.$nextTick(() => {
            this.$refs.detailsContent?.addEventListener('scroll', this.handleDetailsScroll);
            // 初始化标题
            this.headerTitle = '问答';
          });
        })
        .catch(error => {
          console.error(error);
          this.articleDetailsData = {};
        });

      getQAComments(id)
        .then(res => {
          this.commentList = res.data.data.map(item => ({
            ...item,
            isPraised: false // 初始化点赞状态
          }));
        })
        .catch(error => {
          console.error(error);
          this.commentList = [];
        })
    },

    // 关闭详情页
    closeDetails() {
      this.$emit('close');
    },
    handleWriteComment() {
      // 检查登录状态
      const isLoggedIn = localStorage.getItem('isLoggedIn');
      if (isLoggedIn !== 'true') {
        // 未登录，先显示提示，然后显示登录组件
        this.$toast({
          message: '请先登录账号',
          position: 'top',
        });
        setTimeout(() => {
          this.$root.$emit('showLoginRegister', this.$route.path);
        }, 300);
        return;
      }
      this.$toast({
        message: '功能暂未开放，尽请期待',
        position: 'bottom'
      });
    },

    // 从文章详情的json_content中提取p标签文本内容
    extractPTags() {
      // 检查数据是否存在
      if (!this.articleDetailsData?.json_content?.content) {
        return [];
      }

      try {
        // 解码HTML实体
        const decodedContent = this.decodeHtmlEntities(this.articleDetailsData.json_content.content);

        // 解析HTML字符串
        const parser = new DOMParser();
        const doc = parser.parseFromString(decodedContent, 'text/html');

        // 获取所有p标签并提取文本
        const pElements = doc.querySelectorAll('p');

        return Array.from(pElements).map(p => ({
          tag: 'p',
          text: p.textContent.trim() // 去除前后空白
        }));
      } catch (error) {
        console.error('提取p标签失败:', error);
        return [];
      }
    },

    // 从本周精选数据提取图片路径
    extractImgUrls() {
      // 检查数据是否存在
      if (!this.articleDetailsData?.json_content?.content) {
        return [];
      }

      try {
        // 解码HTML实体
        const decodedContent = this.decodeHtmlEntities(this.articleDetailsData.json_content.content);

        // 解析HTML字符串
        const parser = new DOMParser();
        const doc = parser.parseFromString(decodedContent, 'text/html');

        // 获取所有img标签
        const imgElements = doc.querySelectorAll('img');
        const imgList = Array.from(imgElements);

        // 排除第一个img，提取剩余的src
        return imgList.map(img => ({
          tag: 'img',
          src: img.src.trim()
        }));
      } catch (error) {
        console.error('提取img标签失败:', error);
        return [];
      }
    },

    // 解码HTML实体字符为正常文本
    decodeHtmlEntities(str) {
      const tempElement = document.createElement('div');
      tempElement.innerHTML = str;
      // console.log(tempElement.innerHTML);

      return tempElement.innerHTML;
    },

    // 生成2个随机文章id，获取推荐文章详情
    fetchRecommendArticles() {
      // 仅在articleId不为空时执行
      if (!this.articleId) return;

      // 清空现有推荐列表
      this.recommendArticlesList = [];
      this.recommendWeeklyJournalsList = [];

      // 生成4位随机数ID
      const generateRandomId = () => {
        const min = 1280;
        const max = 4480;
        return Math.floor(Math.random() * (max - min + 1)) + min;
      };

      // 递归获取推荐文章
      const fetchArticle = () => {
        // 如果已经有2条推荐，停止请求
        if (this.recommendArticlesList.length >= 2 && this.recommendWeeklyJournalsList.length >= 2) {
          return;
        }

        // 生成不与当前文章ID相同的ID
        let randomId;
        do {
          randomId = generateRandomId().toString();
        } while (randomId === this.articleId.toString());

        // 请求文章数据
        getQADetail(randomId)
          .then(res => {
            // 检查数据是否有效
            if (res && res.data && Object.keys(res.data).length > 0 && res.data.title != "一周的心情｜本周小记精选12580629" && this.recommendArticlesList.length < 2) {
              // 添加到推荐列表
              this.recommendArticlesList.push(res.data);
            }

            if (res && res.data && Object.keys(res.data).length > 0 && res.data.title == "一周的心情｜本周小记精选") {
              // 添加到推荐列表
              this.recommendWeeklyJournalsList.push(res.data);
            }
            // 继续获取下一篇推荐
            fetchArticle();
          })
          // 处理数据获取失败的情况
          .catch(() => {
            fetchArticle();
          });
      };

      // 开始获取第一篇推荐
      fetchArticle();
    },

    // 切换文章的点赞状态，更新点赞数量
    toggleLike(item) {
      // 检查登录状态
      const isLoggedIn = localStorage.getItem('isLoggedIn');
      if (isLoggedIn !== 'true') {
        // 未登录，先显示提示，然后显示登录组件
        this.$toast({
          message: '请先登录账号',
          position: 'top',
        });
        setTimeout(() => {
          this.$root.$emit('showLoginRegister', this.$route.path);
        }, 300);
        return;
      }

      if (item.isLiked) {
        item.praisenum--;
      } else {
        item.praisenum++;
      }
      item.isLiked = !item.isLiked;
    },

    // 切换评论点赞状态，更新点赞数量
    togglePraise(item) {
      if (item.isPraised) {
        item.praisenum--;
      } else {
        item.praisenum++;
      }
      item.isPraised = !item.isPraised;
    },

    // 设置字体大小
    setFontSize(size) {
      this.currentFontSize = size;
    },

    // 滚动到评论列表位置
    scrollToCommentList() {
      // 获取评论列表元素
      const commentListEl = this.$refs.commentList;
      if (commentListEl) {
        // 滚动到评论列表位置
        commentListEl.scrollIntoView({
          behavior: 'smooth', // 平滑滚动效果
          block: 'start' // 对齐到顶部
        });
      }
    },

    // 处理文章详情页头部标题
    handleDetailsScroll() {
      // 使用更可靠的方式获取元素
      const detailsContent = this.$refs.detailsContent;
      if (!detailsContent) return;

      const scrollTop = detailsContent.scrollTop;
      const header = this.$el.querySelector('.article-details-header');
      if (!header) return;

      // 控制标题文本 - 修复始终显示文章标题的问题
      this.headerTitle = scrollTop <= 0 ? '问答' : (this.articleDetailsData.title || '问答');

      // 控制头部位移 - 修复滚动时不收起的问题
      if (scrollTop > this.lastScrollTop && scrollTop > 50) {
        // 向下滚动且超过50px，隐藏头部
        header.style.transform = 'translateY(-100%)';
        header.style.transition = 'transform 0.3s ease';
      } else {
        // 向上滚动或在顶部，显示头部
        header.style.transform = 'translateY(0)';
        header.style.transition = 'transform 0.3s ease';
      }

      // 记录当前滚动位置
      this.lastScrollTop = scrollTop;
    },

    // 处理推荐文章点击事件，重新渲染详情页
    handleRecommendClick(item) {
      // 检查是否点击的是当前文章，如果是则不重新加载
      if (this.articleId.toString() === item.id.toString()) {
        return;
      }

      // 重置滚动位置
      this.lastScrollTop = 0;
      if (this.$refs.detailsContent) {
        this.$refs.detailsContent.scrollTop = 0;
      }

      // 清理之前的状态
      this.recommendArticlesList = [];
      this.recommendWeeklyJournalsList = [];
      this.commentList = [];
      this.articleText = [];
      this.articleImg = [];

      // 通知父组件文章ID变化
      this.$emit('article-change', item.id);
    },
  },
  beforeDestroy() {
    // 移除滚动监听
    this.$refs.detailsContent?.removeEventListener('scroll', this.handleDetailsScroll);
  }
}
</script>

<style scoped lang="less">
.article-details {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: #fff;
  z-index: 1000;
  transition: all 0.3s ease-in-out;

  .article-details-header {
    height: 7vh;
    width: 100vw;
    border-bottom: 1px solid #ececec;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 3vw;
    box-sizing: border-box;
    background-color: #fff;

    .close-details {
      font-size: 14px;
      color: #ccc;
      cursor: pointer;
    }

    .details-header-title {
      font-size: 12px;
      font-weight: 300;
    }
  }

  .article-details-content {
    width: 100vw;
    padding: 3vw;
    box-sizing: border-box;
    height: calc(100vh - 7vh - 7vh);
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;

    .article-details-title {
      padding: 3vh 0;
      font-weight: 500;
    }

    .qustion {
      font-size: 12px;
      font-weight: 350;
      padding: 2vh 0;
      border-bottom: 1px solid #ececec;
      margin-bottom: 4vh;

      .simple_author {
        font-size: 10px;
        padding: 1vh 0;
      }

      .question_brief {
        padding: 2vh 0 1.5vh;
      }
    }

    .simple_answerer {
      font-size: 8px;
      padding: 1vh 0;
    }

    .control-font-size {
      display: flex;
      align-items: center;
      justify-content: flex-end;
      gap: 2vw;
      padding: 1vh 0;
      padding-right: 2vw;
      box-sizing: border-box;
      margin-bottom: 4vh;

      i {
        display: inline-block;
        width: calc(54px / 4);
        height: calc(46px / 4);
        background-size: calc(217px / 4) calc(46px / 4);
        background-repeat: no-repeat;
      }

      .font-sm {
        background-image: url('../assets/sprite/sprite01.png');
        background-position: 0 0;
      }

      .font-bg {
        background-image: url('../assets/sprite/sprite01.png');
        background-position: calc(-82px / 4) 0;
      }

      .font-lg {
        background-image: url('../assets/sprite/sprite01.png');
        background-position: calc(-164px / 4) 0;
      }
    }

    .article-details-img {
      margin-bottom: 3vh;

      img {
        width: 100%;
      }
    }

    .article-details-text {

      p:nth-child(1) {
        color: #525252;
        padding-left: 4vw;
        box-sizing: border-box;
        margin-bottom: 8vh;
      }

      p {
        line-height: 2;
        font-size: 10px;
        margin-bottom: 3vh;
      }
    }

    .article-details-weekimg {
      width: 100%;

      img {
        width: 100%;
      }
    }

    .editor {
      font-size: 8px;
      font-weight: 300;
      color: #2c2c2c;
      padding-bottom: 2vh;
    }

    .copyright {
      font-size: 8px;
      font-weight: 300;
      line-height: 1.4;
      color: #2c2c2c;
    }

    .article-details-author {
      width: 100%;
      margin: 3vh 0;
      display: flex;
      flex-direction: column;
      gap: 2vh;

      span {
        font-size: 10px;
        font-weight: 300;
        padding: 1vh 0 1.8vh;
        position: relative;

        &::after {
          content: '';
          position: absolute;
          bottom: 0;
          left: 0;
          width: 10vw;
          height: 3px;
          background-color: #000;
        }
      }

      .author-box {
        width: 100%;
        height: 5vh;
        display: flex;
        align-items: center;
        justify-content: space-between;

        .author-left {
          height: 100%;
          display: flex;
          align-items: center;
          gap: 2vw;

          .author-avatar {
            height: 90%;
            aspect-ratio: 1/1;
            background-size: cover;
            background-position: center;
            background-repeat: no-repeat;
            border-radius: 50%;
          }

          .author-info {
            display: flex;
            flex-direction: column;
            justify-content: space-between;
            height: 100%;
            padding: 3px 0;
            box-sizing: border-box;

            .author-name {
              font-size: 10px;
              font-weight: 300;
            }

            .author-summary {
              font-size: 8px;
              font-weight: 300;
              color: #8c8c8c;
            }
          }
        }

        .follow-btn {
          font-size: 10px;
          border: 1px solid #aaa;
          color: #aaa;
          padding: 1.5vw 2vw;
          border-radius: 2px;
          box-sizing: border-box;
        }
      }

    }

    .related-recommend {
      width: 100%;
      margin: 3vh 0;
      display: flex;
      flex-direction: column;
      gap: 2vh;

      span {
        font-size: 10px;
        font-weight: 300;
        padding: 1vh 0 1.8vh;
        position: relative;

        &::after {
          content: '';
          position: absolute;
          bottom: 0;
          left: 0;
          width: 10vw;
          height: 3px;
          background-color: #000;
        }
      }

      .recommend-articles {
        display: flex;
        align-items: center;
        gap: 4vw;
        height: 4vh;
        margin: 1vh 0 0;
        cursor: pointer;
        transition: opacity 0.2s ease;

        &:hover {
          opacity: 0.7;
        }

        &:active {
          opacity: 0.5;
        }

        .type {
          white-space: nowrap;
          font-size: 10px;
          color: #aaa;
        }

        .recommend-articles-info {
          height: 100%;
          display: flex;
          flex-direction: column;
          justify-content: space-between;
          font-size: 10px;
        }

        .recommend-articles-author {
          font-weight: 300;
          font-size: 8px;
        }
      }
    }

    .comment-list {
      width: 100%;
      margin: 3vh 0;
      display: flex;
      flex-direction: column;
      gap: 2vh;

      >span {
        font-size: 10px;
        font-weight: 300;
        padding: 1vh 0 1.8vh;
        position: relative;

        &::after {
          content: '';
          position: absolute;
          bottom: 0;
          left: 0;
          width: 10vw;
          height: 3px;
          background-color: #000;
        }
      }

      .comment-list-item {
        width: 100%;
        min-height: 10vh;
        border-bottom: 1px solid #ddddddd7;

        .comment-list-item-head {
          display: flex;
          align-items: center;
          justify-content: space-between;
          height: 20%;
          width: 100%;
          margin-bottom: 2vh;

          .comment-list-item-user {
            display: flex;
            align-items: center;
            gap: 1vw;
            height: 100%;

            .comment-user-avatar {
              height: 2vh;
              aspect-ratio: 1/1;
              border-radius: 50%;
              background-size: cover;
              background-position: center;
              background-repeat: no-repeat;
            }

            .comment-user-name {
              font-size: 10px;
              font-weight: 300;
              color: #aaa;
            }
          }

          .comment-input-date {
            font-size: 8px;
            font-weight: 300;
          }
        }

        .quoted-comment,
        .comment-content {
          width: 95%;
          margin-left: 5%;
          font-size: 10px;
          font-weight: 350;
          margin-bottom: 2vh;
          line-height: 1.8;
        }

        .quoted-comment {
          border: 1px solid #ddd;
          padding: 1.2vh 2vw;
          box-sizing: border-box;
          border-radius: 4px;
        }

        .comment-function-icon {
          display: flex;
          align-items: center;
          justify-content: flex-end;
          gap: 3vw;
          padding-right: 5vw;
          margin-bottom: 1vh;

          i {
            display: inline-block;
            width: 12px;
            height: 12px;
            background-size: cover;
            background-position: center;
            background-repeat: no-repeat;
          }

          >i {
            background-image: url(../assets/detail-icon/comment.svg);
          }

          .praise {
            display: flex;
            align-items: center;
            gap: 1vw;
            font-size: 8px;
            color: #aaa;
          }
        }

      }
    }

  }

  .article-details-bottom {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100vw;
    height: 6vh;
    z-index: 1;
    padding: 0 3vw;
    box-sizing: border-box;
    background-color: #f7f7f7;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .write-comments {
      height: 60%;
      font-size: 10px;
      color: #cdcdcd;
      background-color: #fff;
      padding: 0 2vw;
      padding-right: 8vw;
      box-sizing: border-box;
      border: 1px solid #a8a8a8a4;
      border-radius: 4px;
      display: flex;
      align-items: center;
    }

    .bottom-function-icon {
      display: flex;
      align-items: center;
      gap: 4vw;

      .like span,
      .comment span {
        font-size: 8px;
        color: #cdcdcd;
      }

      .like,
      .comment {
        display: flex;
        align-items: flex-start;
      }

      .like {
        gap: 3px;
      }

      .comment>i {
        display: block;
        width: 12px;
        height: 12px;
        background-image: url(../assets/detail-icon/comment.svg);
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
      }

      .one-icon {
        font-size: 12px;
        color: #cdcdcd;
      }
    }
  }
}

.loading {
  width: 100%;
  text-align: center;
  padding: 20px;
  font-size: 14px;
  color: #999;
}
</style>